using System;
using System.Linq;
using System.Threading.Tasks;
using Grpc.Core;
using Grpc.Core.Interceptors;

namespace RealTimeChat.Services
{
    public class AuthInterceptor : Interceptor
    {
        private bool ValidateToken(string token) => /* your logic */ true;

        // 无返回值版本
        private async Task HandleAuthAsync(ServerCallContext context, Func<Task> next)
        {
            var header = context.RequestHeaders
                .FirstOrDefault(h => h.Key.Equals("authorization", StringComparison.OrdinalIgnoreCase))
                ?.Value;
            var token = header?.Replace("Bearer ", "");
            if (string.IsNullOrEmpty(token) || !ValidateToken(token))
                throw new RpcException(new Status(StatusCode.Unauthenticated, "Invalid token"));
            await next();
        }

        // 有返回值版本
        private async Task<T> HandleAuthAsync<T>(ServerCallContext context, Func<Task<T>> next)
        {
            var header = context.RequestHeaders
                .FirstOrDefault(h => h.Key.Equals("authorization", StringComparison.OrdinalIgnoreCase))
                ?.Value;
            var token = header?.Replace("Bearer ", "");
            if (string.IsNullOrEmpty(token) || !ValidateToken(token))
                throw new RpcException(new Status(StatusCode.Unauthenticated, "Invalid token"));
            return await next();
        }

        public override Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
            TRequest request, ServerCallContext context,
            UnaryServerMethod<TRequest, TResponse> continuation) =>
            HandleAuthAsync(context, () => base.UnaryServerHandler(request, context, continuation));

        public override Task ServerStreamingServerHandler<TRequest, TResponse>(
            TRequest request, IServerStreamWriter<TResponse> responseStream,
            ServerCallContext context,
            ServerStreamingServerMethod<TRequest, TResponse> continuation) =>
            HandleAuthAsync(context, () => base.ServerStreamingServerHandler(request, responseStream, context, continuation));

        public override Task<TResponse> ClientStreamingServerHandler<TRequest, TResponse>(
            IAsyncStreamReader<TRequest> requestStream,
            ServerCallContext context,
            ClientStreamingServerMethod<TRequest, TResponse> continuation) =>
            HandleAuthAsync(context, () => base.ClientStreamingServerHandler(requestStream, context, continuation));

        public override Task DuplexStreamingServerHandler<TRequest, TResponse>(
            IAsyncStreamReader<TRequest> requestStream,
            IServerStreamWriter<TResponse> responseStream,
            ServerCallContext context,
            DuplexStreamingServerMethod<TRequest, TResponse> continuation) =>
            HandleAuthAsync(context, () => base.DuplexStreamingServerHandler(requestStream, responseStream, context, continuation));
    }
}
